﻿using System;
using System.Collections.Generic;
using VideoServices.Common.Enum;
using VideoServices.Domain.Entities;

namespace VideoServices.Business.Facade
{
    /// <summary>
    /// VideoServicesFacade implemented with singleton pattern.
    /// </summary>
    /// <remarks>
    /// Based on http://www.yoda.arachsys.com/csharp/singleton.html
    /// </remarks>
    public sealed class VideoServicesFacade
    {
        #region Fields

        static readonly VideoServicesFacade instance = new VideoServicesFacade();

        /// <summary>
        /// Gets the only instance of this singleton.
        /// </summary>
        /// <value>The instance.</value>
        public static VideoServicesFacade Instance
        {
            get
            {
                return instance;
            }
        }

        #endregion

        #region Constructor

        // Explicit static constructor to tell C# compiler not to mark type as beforefieldinit
        // ReSharper disable EmptyConstructor
        static VideoServicesFacade()
        {
        }

        private VideoServicesFacade()
        {
        }

        #endregion

        #region Facade Methods

        #region Customer

        /// <summary>
        /// Creates a customer.
        /// </summary>
        /// <param name="newCustomer">The new customer.</param>
        /// <returns></returns>
        public Customer CreateCustomer(Customer newCustomer)
        {
            var businessObject = new CustomerBusinessObject();
            return businessObject.CreateCustomer(newCustomer);
        }

        /// <summary>
        /// Gets the customer by id.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns></returns>
        public Customer GetCustomerById(int id)
        {
            var businessObject = new CustomerBusinessObject();
            return businessObject.GetCustomerById(id);
        }

        #endregion

        #region Video

        /// <summary>
        /// Creates the video.
        /// </summary>
        /// <returns></returns>
        public Catalogue CreateVideo(Catalogue newVideo)
        {
            var businessObject = new CatalogueBusinessObject();
            return businessObject.CreateVideo(newVideo);
        }

        /// <summary>
        /// Gets the video by id.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns></returns>
        public Catalogue GetVideoById(int id)
        {
            var businessObject = new CatalogueBusinessObject();
            return businessObject.GetVideoById(id);
        }
        
        /// <summary>
        /// Gets the video by genre.
        /// </summary>
        /// <param name="genreName">Name of the genre.</param>
        /// <returns></returns>
        public IEnumerable<Catalogue> GetVideoByGenre(string genreName)
        {
            var businessObject = new CatalogueBusinessObject();
            return businessObject.GetVideosByGenre(genreName);
        }

        /// <summary>
        /// Gets the video by catalogue number.
        /// </summary>
        /// <param name="number">The number.</param>
        /// <returns></returns>
        public Catalogue GetVideoByCatalogueNumber(string number)
        {
            var businessObject = new CatalogueBusinessObject();
            return businessObject.GetVideoByNumber(number);
        }

        /// <summary>
        /// Gets the videos by director.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <returns></returns>
        public IEnumerable<Catalogue> GetVideosByDirector(string name)
        {
            var businessObject = new CatalogueBusinessObject();
            return businessObject.GetVideosByDirector(name);
        }

        #endregion

        #region Stock

        /// <summary>
        /// Creates a stock.
        /// </summary>
        /// <param name="newStockItem">The new stock item.</param>
        /// <returns></returns>
        public Stock CreateItem(Stock newStockItem)
        {
            var businessObject = new StockBusinessObject();
            return businessObject.CreateItem(newStockItem);
        }

        /// <summary>
        /// Gets the stock by id.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns></returns>
        public Stock GetItemById(int id)
        {
            var businessObject = new StockBusinessObject();
            return businessObject.GetItemById(id);
        }

        /// <summary>
        /// Gets the item by warehouse.
        /// </summary>
        /// <param name="warehouse">The warehouse.</param>
        /// <returns></returns>
        public IEnumerable<Stock> GetItemsByWarehouse(Warehouse warehouse)
        {
            var businessObject = new StockBusinessObject();
            return businessObject.GetItemsByWarehouse(warehouse);
        }

        /// <summary>
        /// Updates the stock level.
        /// </summary>
        /// <param name="catalogue">The catalogue.</param>
        /// <param name="warehouse">The warehouse.</param>
        /// <param name="quantity">The quantity.</param>
        /// <param name="action">The action.</param>
        public void UpdateStockLevel(Catalogue catalogue, Warehouse warehouse, int quantity, StockLevelAction action)
        {
            var businessObject = new StockBusinessObject();
            businessObject.UpdateStockLevel(catalogue, warehouse, quantity, action);
        }

        #endregion

        #region Order

        /// <summary>
        /// Creates a order.
        /// </summary>
        /// <param name="newOrder">The new order.</param>
        /// <returns></returns>
        public Order CreateOrder(Order newOrder)
        {
            var businessObject = new OrderBusinessObject();
            return businessObject.CreateOrder(newOrder);
        }

        /// <summary>
        /// Gets the order by id.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns></returns>
        public Order GetOrderById(Guid id)
        {
            var businessObject = new OrderBusinessObject();
            return businessObject.GetOrderById(id);
        }

        #endregion

        #region Delivery

        /// <summary>
        /// Creates a delivery.
        /// </summary>
        /// <param name="delivery">The delivery.</param>
        /// <returns></returns>
        public Delivery CreateDelivery(Delivery delivery)
        {
            var businessObject = new DeliveryBusinessObject();
            return businessObject.CreateDelivery(delivery);
        }

        /// <summary>
        /// Gets the delivery by id.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns></returns>
        public Delivery GetDeliveryById(Guid id)
        {
            var businessObject = new DeliveryBusinessObject();
            return businessObject.GetDeliveryById(id);
        }

        #endregion

        #region Warehouse

        /// <summary>
        /// Gets the warehouse by id.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns></returns>
        public Warehouse GetWarehouseById(int id)
        {
            var businessObject = new WarehouseBusinessObject();
            return businessObject.GetWarehouseById(id);
        }

        /// <summary>
        /// Creates the warehouse.
        /// </summary>
        /// <param name="newWarehouse">The new warehouse.</param>
        /// <returns></returns>
        public Warehouse CreateWarehouse(Warehouse newWarehouse)
        {
            var businessObject = new WarehouseBusinessObject();
            return businessObject.CreateWarehouse(newWarehouse);
        }

        #endregion

        #region Store

        /// <summary>
        /// Gets the store by id.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns></returns>
        public Store GetStoreById(int id)
        {
            var businessObject = new StoreBusinessObject();
            return businessObject.GetStoreById(id);
        }

        /// <summary>
        /// Creates the store.
        /// </summary>
        /// <param name="newStore">The new store.</param>
        /// <returns></returns>
        public Store CreateStore(Store newStore)
        {
            var businessObject = new StoreBusinessObject();
            return businessObject.CreateStore(newStore);
        }

        #endregion

        #endregion
    }
}
